package com.yunhe.history.util;


import com.yunhe.history.domain.data.ChargeAndDischargeCurve;
import com.yunhe.common.model.data.Measurement;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TreeMap;

public class CurveUtils {

    /**
     * 根据一条曲线整正负方向,将其进行切割同时计算了他的积分面积
     * Note:负数表示为充电,正数表示为放电
     * @param measurements
     * @param date
     * @return
     */
    public static ChargeAndDischargeCurve getChargeAndDischargeCurve(List<Measurement> measurements, String date) {
        ChargeAndDischargeCurve chargeAndDischarge = new ChargeAndDischargeCurve();
        List<TreeMap<Date, Double>> chargeMeasMaps = new ArrayList<>();
        List<TreeMap<Date, Double>> disChargeMeasMaps = new ArrayList<>();
        List<TreeMap<Date, Double>> unkwonMeasMaps = new ArrayList<>();
        Integer lastCurveIndex = 0;
        if (measurements == null || measurements.size() <= 2) {
            return new ChargeAndDischargeCurve();
        }
        for (int i = 0; i < measurements.size() - 1; i++) {
            int j = i + 1;
            Double startValue = measurements.get(i).getVal();
            Double startValue2 = measurements.get(j).getVal();
            if (startValue == 0 && startValue2 == 0) {
                lastCurveIndex = j;
            }
            //充电变放电 特殊注意
            if (startValue < 0 && startValue2 >= 0) {
                if (startValue2 == 0.0) {
                    TreeMap<Date, Double> doubles = toChargeOrDischargeCurvePoint(measurements, lastCurveIndex, j + 1);
                    chargeMeasMaps.add(doubles);
                } else {
                    if (j - lastCurveIndex > 1) {
                        TreeMap<Date, Double> doubles = toChargeOrDischargeCurvePoint(measurements, lastCurveIndex, j);
                        chargeMeasMaps.add(doubles);
                    }
                    TreeMap<Date, Double> dateDoubleTreeMap = toChargeOrDischargeCurvePoint(measurements, i, j + 1);
                    unkwonMeasMaps.add(dateDoubleTreeMap);
                }
                lastCurveIndex = j;
            }
            //放电变充电
            if (startValue > 0 && startValue2 <= 0) {
                if (startValue2 == 0.0) {
                    TreeMap<Date, Double> doubles = toChargeOrDischargeCurvePoint(measurements, lastCurveIndex, j + 1);
                    disChargeMeasMaps.add(doubles);
                } else {
                    if (j - lastCurveIndex > 1) {
                        TreeMap<Date, Double> doubles = toChargeOrDischargeCurvePoint(measurements, lastCurveIndex, j);
                        disChargeMeasMaps.add(doubles);
                    }
                    TreeMap<Date, Double> dateDoubleTreeMap = toChargeOrDischargeCurvePoint(measurements, i, j + 1);
                    unkwonMeasMaps.add(dateDoubleTreeMap);
                }
                lastCurveIndex = j;
            }

            //当日的最后一个时间段没有发生切换时判断最后一个是什么曲线
            if (j == measurements.size() - 1) {
                if (startValue <= 0 && startValue2 <= 0) {
                    TreeMap<Date, Double> doubles = toChargeOrDischargeCurvePoint(measurements, lastCurveIndex, j + 1);
                    chargeMeasMaps.add(doubles);
                } else if (startValue >= 0 && startValue2 >= 0) {
                    TreeMap<Date, Double> doubles = toChargeOrDischargeCurvePoint(measurements, lastCurveIndex, j + 1);
                    disChargeMeasMaps.add(doubles);
                }
            }
        }
        chargeAndDischarge.setChargeCurve(chargeMeasMaps);
        chargeAndDischarge.setDisChargeCurve(disChargeMeasMaps);
        chargeAndDischarge.setUnkwonMeasMaps(unkwonMeasMaps);
        chargeAndDischarge.setDate(date);
        chargeAndDischarge.calculatingPoints();
        return chargeAndDischarge;
    }


    /**
     * 将量测对象排序后转换为java.util.Map<Date,Double>
     *
     * @param meas
     * @param start
     * @param end
     * @return方便计算
     */
    private static TreeMap<Date, Double> toChargeOrDischargeCurvePoint(List<Measurement> meas, int start, int end) {
        TreeMap<Date, Double> doubles = new TreeMap<>(Date::compareTo);
        List<Measurement> measurements = meas.subList(start, end);
        for (Measurement m : measurements) {
            doubles.put(new Date(m.getRtime()), m.getVal());
        }
        return doubles;
    }
}
